package renpyas3.view.instructions
{
	import flash.display.Bitmap;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import org.osflash.thunderbolt.Logger;
	import renpyas3.model.RenpyPlayerModel;
	import renpyas3.view.components.TransitionEngine;
	import renpyas3.view.RenpyPlayer;
	
	/**
	 * show a background image
	 */
	public class ViewInstruction_scene extends ViewInstruction
	{
		public static const NAME:String = "scene";
		
		private var _view:RenpyPlayer;
		private var _model:RenpyPlayerModel;
		private var _params:Object;
		private var _transitionName:String;
		private var _bgToShowImageName:String;
		private var _oldImageAlreadyReplacedByNew:Boolean;
		
		public function ViewInstruction_scene() 
		{
			_oldImageAlreadyReplacedByNew = false;
		}
		
		/**
		 * execute a the code for this command, altering RenpyPlayerViewState
		 * @param	view  is the whole set of view state variables and operations that make up the VIEW
		 * @param	model the data needed to play a renpy novel
		 * @param	params   extra data for some instructions
		 */
		override public function execute(view:RenpyPlayer, model:RenpyPlayerModel, params:Object=null):void
		{
			_view = view;
			_model = model;
			_params = params;
			
			_bgToShowImageName = params.imageName;
			_transitionName = params.transition;

			if (_view.imagesLayer.numChildren > 0)
			{
				_view.imagesLayer.removeChildAt(0);
			}

			if (_transitionName == "" || _view.backgroundLayer.alpha == 0 || _view.backgroundLayer.numChildren == 0)
			{
				//nothing to animate
				afterFadeOut();
			}
			else
			{
				//fade out this image
				//_view.backgroundLayer.alpha = 1;
				_view.transtionEngine.startTransition(_transitionName, _view.backgroundLayer);
				_view.transtionEngine.addEventListener(TransitionEngine.TRANSITION_FINISHED, handleFadeOutFinished, false, 0, true);
			}
		}			
		
		private function handleFadeOutFinished(e:Event=null):void 
		{
			Logger.info("ViewInstruction_scene::handleFadeOutFinished called"); 
			
			_view.transtionEngine.removeEventListener(TransitionEngine.TRANSITION_FINISHED, handleFadeOutFinished);
			afterFadeOut();
		}
		
		/**
		 * called when first half of the transition 
		 * (fade out of the old image, or just show it straightaway))
		 * is finished
		 */
		private function afterFadeOut():void
		{
			Logger.info("ViewInstruction_scene::afterFadeOut --bgToShow:"+_bgToShowImageName+"  --_transitionName:"+_transitionName );

			replaceOldImageByNew();
			
			if (_transitionName == "")
			{
				_view.backgroundLayer.alpha = 1;
				afterNewImageAdded()
			}
			else
			{
				_view.backgroundLayer.alpha = 0;
				_view.transtionEngine.startTransition(_transitionName, _view.backgroundLayer);
				_view.transtionEngine.addEventListener(TransitionEngine.TRANSITION_FINISHED, handleNewImageFadeInFinished,false,0,true);
			}
		}
		
		private function replaceOldImageByNew():void
		{
			Logger.info("ViewInstruction_scene::replaceOldImageByNew --bgToShow:"+_bgToShowImageName+"  --_transitionName:"+_transitionName );
			
			if (_view.backgroundLayer.numChildren > 0)
			{
				_view.backgroundLayer.removeChildAt(0);
			}
			

			//scene can use a colorfill or an image
			if (_params.useColor == true)
			{
				//Logger.info("use color:", params.color);
				//use color
				var colorLayer:Sprite = new Sprite();
				colorLayer.graphics.beginFill(_params.color);
				colorLayer.graphics.drawRect(0, 0, _view.imagesLayer.stage.stageWidth, _view.imagesLayer.stage.stageHeight);
				colorLayer.graphics.endFill();
				_view.backgroundLayer.addChild(colorLayer);
			}
			else if (_model.currentScreen.imagesForThisScreen[_bgToShowImageName])
			{
				//var bgToShowPtr:Loader = _model.currentScreen.imagesForThisScreen[_bgToShowImageName].loader;
				var pathAndFilename:String = _model.currentScreen.imagesForThisScreen[_bgToShowImageName].pathAndFilename;
				var bgToShowPtr:Bitmap = _model.assetsLoader.getBitmap(pathAndFilename) as Bitmap;
				var scaleFactorX:Number = _view.imagesLayer.stage.stageWidth / _model.options.screenWidth;
				var scaleFactorY:Number = _view.imagesLayer.stage.stageHeight/ _model.options.screenHeight;
				bgToShowPtr.scaleX = scaleFactorX;
				bgToShowPtr.scaleY = scaleFactorY;						
				_view.backgroundLayer.addChild(bgToShowPtr);
			}
			
			//mark as replaced so the abort command wouldn't need to do this again if called
			_oldImageAlreadyReplacedByNew = true;
		}
		
		private function handleNewImageFadeInFinished(e:Event):void
		{
			Logger.info("ViewInstruction_scene::handleNewImageFadeInFinished called"); 
			_view.transtionEngine.removeEventListener(TransitionEngine.TRANSITION_FINISHED, handleNewImageFadeInFinished);
			afterNewImageAdded();
		}

		/**
		 * called when second half of the transition 
		 * (fade in of the new image, or just show it straightaway)
		 * is finished
		 */
		private function afterNewImageAdded():void
		{
			//all done in this command
			_view.instructionsProcessor.instructionFinished();	
			
			//clean references
			_view = null;
			_model = null;
		}
		
		/**
		 * finish immediately, FastForward actions
		 */
		override public function abort():void
		{
			if (_view)
			{
				Logger.info("ViewInstruction_scene::abort --_oldImageAlreadyReplacedByNew:"+_oldImageAlreadyReplacedByNew+"  _view.transtionEngine.hasEventListener"+_view.transtionEngine.hasEventListener(TransitionEngine.TRANSITION_FINISHED));
				
				if (_transitionName != "")
				{
					//is is still animating
					if (_view.transtionEngine.hasEventListener(TransitionEngine.TRANSITION_FINISHED))
					{
						Logger.info("ViewInstruction_scene::abort is is still animating");
						_view.transtionEngine.removeEventListener(TransitionEngine.TRANSITION_FINISHED, handleFadeOutFinished);
						_view.transtionEngine.removeEventListener(TransitionEngine.TRANSITION_FINISHED, handleNewImageFadeInFinished);
						_view.transtionEngine.fforwardTransition();
						_view.backgroundLayer.alpha = 1;
					}
				}

				if (_oldImageAlreadyReplacedByNew == false)
				{
					replaceOldImageByNew();
				}
				
				afterNewImageAdded()
			}
		}
	}
}